/*
 * SimularTorneo.java
 *
 * Created on 16 de abril de 2007, 19:01
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package futbol.simulaciones;

import futbol.Partido;
import futbol.tacticas.concursantes.Tactica;
import futbol.tacticas.concursantes.TacticaVacia;
import futbol.tacticas.concursantes.Concursantes;

import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Properties;

/**
 *
 * @author Jorge
 */
public class SimuladorTorneo {
    
    private Tactica tacticasAceptadas[]=Concursantes.getTodasLasTacticas();  //Obtiene todas las tcticas
    private Hashtable<String, Integer> victorias=new Hashtable<String, Integer>();

    private boolean buscarElemento(ArrayList<Integer> elementos, int nElementoABuscar, int nIndexDesde, int nContarElementos )
    {
        int nContar=0;
        for (int n=0;n<nContarElementos;n++)
            if (elementos.get(n+nIndexDesde).intValue()==nElementoABuscar)
                if (++nContar==2) return true;
        return false;
    }
    

    //Devuelve un reparto aleatorio organizando los equipos en grupos de 16 jugadores para que no se enfrenten buenos equipos en las primeras fases. 
    private ArrayList<Integer> getAsignacionesAleatorias(){
        //************** Reparto aleatorio ***************
        int nTotalGrupos=16;
        int nG=128/nTotalGrupos;  //Equipos por grupo.
        boolean bGrupoEnTorneo[][]=new boolean[nTotalGrupos][nG];  //Creamos una matriz de booleanos indicando cual se ha obtenido o no.
        boolean bGrupoTomado[]=new boolean[nTotalGrupos];  //Para que no coincidan en la segunda o tercera fase, por cada iteracin solo se podr tomar un grupo.
        ArrayList<Integer> ganadores=new ArrayList<Integer>();  //Crea un ArrayList con los ganadores
        System.out.println("Iniciando reparto aleatorio ");
        for (int z=0;z<nG;z++){
            //Se ha ordenado los jugadores segn una preliga y se organizar en 16 grupos de 8 participantes.
            for (int n=0;n<bGrupoTomado.length;n++) 
                bGrupoTomado[n]=false;  //Inicializamos el vector
            for (int n=0;n<nTotalGrupos/2;n++){  //Hay ocho grupos para que lleguen los importanten a octavos.
                int nGrupo, nPosGrupo, nGrupo2, nPosGrupo2;
                do{
                    nGrupo=(int)(Math.random()*nTotalGrupos); 
                }while(bGrupoTomado[nGrupo]==true);
                nGrupo2=(nGrupo+(nTotalGrupos/2))%nTotalGrupos;
                bGrupoTomado[nGrupo]=bGrupoTomado[nGrupo2]=true;
                do{
                    nPosGrupo=(int)(Math.random()*nG);
                }while(bGrupoEnTorneo[nGrupo][nPosGrupo]==true);
                bGrupoEnTorneo[nGrupo][nPosGrupo]=true;
                do{
                    nPosGrupo2=(int)(Math.random()*nG);
                }while(bGrupoEnTorneo[nGrupo2][nPosGrupo2]==true);
                bGrupoEnTorneo[nGrupo2][nPosGrupo2]=true;

                ganadores.add(new Integer(nGrupo*nG+nPosGrupo));
                ganadores.add(new Integer(nGrupo2*nG+nPosGrupo2));
            }
        }
        return ganadores;
    }
    
    private String formatInt(int a){
        String dev=""+a;
        while (dev.length()<2)
            dev="0" + dev;
        return dev + "-";
    }

    private String getRutaPartido(int nFase, Tactica t1, Tactica t2){
        String sCarpetas[]={
            "0_PrimeraFase", //0
            "1_SegundaFase", //1
            "2_TerceraFase", //2
            "3_Octavos", //3
            "4_Cuartos", //4
            "5_Semifinal", //5
            "6_Final" //6
        };
        try{
            
            //Crea el directorio si no existe.
            String sR="torneo";
            File fDir=new File(sR);
            if (!fDir.exists()) fDir.mkdir();
            
            //Crea el directorio si no existe.
            sR+="/" + sCarpetas[nFase];
            fDir=new File(sR);
            if (!fDir.exists()) fDir.mkdir();
            
            //Guarda el fichero
            return sR + "/" + formatInt(nFase) + t1.getNombre() + " vs " + t2.getNombre() + ".jvc";
        }catch(Exception e){
            e.printStackTrace();
        }
        return "aux.jvc";
    }
    
    private void guardarLinea(OutputStream out, String sTexto) throws Exception{
        sTexto += "\n";
        out.write(sTexto.getBytes() );
    }
    
    private void simular() throws Exception{
        ArrayList<Integer> ganadores= getAsignacionesAleatorias(); 
        
        
        //************ Se disputan los partidos *************
        System.out.println("Inicio del torneo");
        ArrayList<Integer> pendientesDeJuego;
        int nFase=0;
        FileOutputStream fos=new FileOutputStream("resultados.cvs");
        DataOutputStream dos=new DataOutputStream(fos);
        while(ganadores.size()>1){
            System.out.println("-----  FASE : " + nFase +  " -----" );
            guardarLinea(dos, "FASE :" + nFase);
            pendientesDeJuego=ganadores;
            ganadores=new ArrayList<Integer>();
            
            int nPa=0;
            while(pendientesDeJuego.size()>0){
                tacticasAceptadas=Concursantes.getTodasLasTacticas();  
                Integer i[]={pendientesDeJuego.get(0), pendientesDeJuego.get(1)};
                Tactica t1=tacticasAceptadas[i[0]];  //Obtiene las tcticas
                Tactica t2=tacticasAceptadas[i[1]];  //Obtiene las tcticas
                Partido p=new Partido(t1, t2, getRutaPartido(nFase, t1, t2));
                pendientesDeJuego.remove(1);
                pendientesDeJuego.remove(0);
                int nGana=-1;
                if (t1.getNombre()==TacticaVacia.TEXTO_TACTICA_VACIA) nGana=1;
                if (t2.getNombre()==TacticaVacia.TEXTO_TACTICA_VACIA) nGana=0;
                if (nGana==-1){
                    for (int z=0;z<1800;z++){
                        p.mover();
                    }
                    nGana=p.getGanador();
                    System.out.println(p.getTactica(0).getNombre() + ":" + p.getPuntos(0) + "-" + 
                        p.getTactica(1).getNombre() + ":" + p.getPuntos(1) + " (Gana:" + p.getTactica(nGana).getNombre() + ")");
                    guardarLinea(dos, p.getTactica(0).getNombre() + ";" + p.getPuntos(0) + ";" + p.getTactica(1).getNombre() + ";" + p.getPuntos(1) + ";" + p.getTactica(nGana).getNombre());
                }else{
                    System.out.println(p.getTactica(nGana).getNombre() + " pasa a la siguiente fase");
                    guardarLinea(dos, p.getTactica(nGana).getNombre() + " pasa a la siguiente fase;");
                }
                ganadores.add(i[nGana]);  //Almacena el indice de la tctica ganadora.
                System.gc();  //Realiza la recoleccin de basura
                nPa++;
            }
            nFase++;
        }
        dos.close();
        tacticasAceptadas=Concursantes.getTodasLasTacticas();  //Vuelve a generar todas las tcticas. Poco eficiente en un futuro revisar instanciar las dos que queremos que jueguen.
        Integer iGana=ganadores.get(0);
        String sNombre=tacticasAceptadas[iGana].getNombre();
        if (!victorias.containsKey(sNombre))
            victorias.put(sNombre, new Integer(0));
        Integer i=(Integer)victorias.get(sNombre);
        i=new Integer(i.intValue())+1;
        victorias.put(sNombre, i);
    }

    private void visualizarResultados(){
        System.out.println("TOTAL RESULTADOS");
        for (Tactica t:tacticasAceptadas){
            if (victorias.containsKey(t.getNombre())){
                System.out.println(t.getNombre() + victorias.get(t.getNombre()));
            }
        }
    }
    
    public static void main(String arg[]){
        SimuladorTorneo sl=new SimuladorTorneo();
        for (int n=0;n<1;n++){
            System.out.println("Torneo:" + n + " -------------------------");
            try{
                sl.simular();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
        sl.visualizarResultados();
        
    }
    
}
